﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;

namespace internal_website.Models.jQueryDataTables
{
    public class JQueryDataTablesAjaxHandler<T> where T : class
    {
        //from c in entireCollection
        //where AnyOfPatternsIsFoundInAnyOfTheseStringsToExamine(new List<string> { c.LastName, c.FirstName }, new List<string>(reg))//in which column should we search for data?
        //select new[] { Convert.ToString(c.Id), Convert.ToString(c.Active), Convert.ToString(c.LastName), Convert.ToString(c.FirstName) };
        private DbSet<T> dbSet;
        public JQueryDataTablesAjaxHandler(DbSet<T> set )
        {
            dbSet = set;
        } 
        public JsonResult DataTablesAjaxHandler(jQueryDataTableParamModel param)
        {
            var delimiterSequence = " ".ToCharArray();
            var regexSearchPtns = RegexSearchPtns(param.sSearch, delimiterSequence);
            //var filteredEntities = FilteredCollection(param.sSearch,);
            
            return null;
        }


        #region Search

        /// <summary>
        /// Splits a string based on character delimitier into a List&lt;string;gt 
        /// </summary>
        /// <param name="sSearch">Input string that contaikns "multiple" regexes</param>
        /// <param name="charDelimiter">Character delimiter</param>
        /// <returns></returns>
        private List<string> RegexSearchPtns(string searchTerm , char[] charDelimiter)
        {
            var reg = searchTerm == null ? new[] { ".*" } : searchTerm.Split(charDelimiter);
            return reg.ToList();
        }

        /// <summary>
        /// Returns a serie of matched strings from a certain regex pattern
        /// </summary>
        /// <param name="regexPtn">The pattern to search for</param>
        /// <param name="stringsToExamine">Sthe strinrgs for examination</param>
        /// <returns></returns>
        private List<string> TheseStringsHoldsThePattern(string regexPtn, List<string> stringsToExamine)
        {
            var reg = new System.Text.RegularExpressions.Regex(regexPtn);
            var result = new List<string>();
            foreach (var str in stringsToExamine)
            {
                if (reg.IsMatch(str)) result.Add(str);
            }
            return result;
        }

        /// <summary>
        /// Tells if the provided pattern is found in the examined strings.
        /// Example: 
        ///     stringsToExamine = { "kalle", "pelle", "lisa", "rosa" }
        ///     regexPtn = "^sa"
        ///     Will return false!   
        /// </summary>
        /// <param name="regexPtn">The regex pattern to search for</param>
        /// <param name="stringsToExamine">A serie of strings to be examined</param>
        /// <returns></returns>
        private bool PatternIsFoundInAnyOfTheseStrings(string regexPtn, List<string> stringsToExamine)
        {
            var reg = new System.Text.RegularExpressions.Regex(regexPtn);

            //does any condition satisfy the condition?
            var conditionSatisfied = stringsToExamine.Any(str => reg.IsMatch(str));
            return conditionSatisfied;
        }

        /// <summary>
        /// Tells if any of the provided pattern are found in the examined strings.
        /// Example: 
        ///     stringsToExamine = { "kalle", "pelle", "lisa", "rosa" }
        ///     regPtns = { "le", "pe", "ls", "^sa" }
        ///     Will return true!   
        /// </summary>
        /// <param name="regPtns">A serie of regex patterns to search for</param>
        /// <param name="stringsToExamine">A serie of strings to be examined</param>
        /// <returns></returns>
        public bool AnyOfPatternsIsFoundInAnyOfTheseStringsToExamine(List<string> regPtns, List<string> stringsToExamine)
        {
            var anyOfPatternsIsFoundInAnyOfTheseStringsToExamine =
                regPtns.Any(currentPtn => PatternIsFoundInAnyOfTheseStrings(currentPtn, stringsToExamine));

            return anyOfPatternsIsFoundInAnyOfTheseStringsToExamine;
        }

        #endregion

        private IQueryable<T> EntireCollection()
        {
            var entireCollection = from c in dbSet
                                   select c;
            return entireCollection;
        }

        private IEnumerable<T> FilteredCollection<T>(IQueryable<T> queryable, List<string> regPtns, params Expression<Func<T, object>>[] regComlumns)
        {
            var doas = queryable.Where()
            //var quer = from x in queryable
            //           where AnyOfPatternsIsFoundInAnyOfTheseStringsToExamine(regPtns, regComlumns)
            //           select x;

            return quer;
        }

        private string PropertyName(Expression<Func<T, object>> expression)
        {
            var body = expression.Body as MemberExpression;

            if (body == null)
            {
                body = ((UnaryExpression)expression.Body).Operand as MemberExpression;
            }

            return body.Member.Name;
        }

    }
}